﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Serialization;

namespace SSG.Model
{
    /// <summary>
    /// Setting model, mainly for enumerations
    /// </summary>
    [Serializable]
    [XmlInclude(typeof (Setting.SettingValues))]
    public class Setting
    {
        public static readonly List<Setting> AllSettings = new List<Setting>();
        public static readonly List<Setting> RunwayDesignatorInclusionOptions = new List<Setting>();
        public static readonly List<Setting> OrderBy = new List<Setting>();
        public static Setting NotSet = new Setting(SettingValues.NotSet);
        public static Setting OrderByRunway = new Setting(SettingValues.OrderByRunway);
        public static Setting NoOrder = new Setting(SettingValues.NoOrder);
        public static Setting OrderBySidStarTransition = new Setting(SettingValues.OrderBySidStarTransition);

        /// <summary>
        /// Settings, ensure unique settings 
        /// </summary>
        [Serializable]
        public enum SettingValues
        {
            NotSet,
            NoOrder,
            OrderByRunway,
            OrderBySidStarTransition
        }

        /// <summary>
        /// Static constructor
        /// </summary>
        static Setting()
        {
            Setting.OrderBy.Add(NoOrder);
            Setting.OrderBy.Add(OrderByRunway);
            Setting.OrderBy.Add(OrderBySidStarTransition);

            // All
            Setting.AllSettings.Add(NotSet);
            Setting.AllSettings.Add(OrderBySidStarTransition);
            Setting.AllSettings.Add(OrderByRunway);
            Setting.AllSettings.Add(NoOrder);
        }

        /// <summary>
        /// Default constructor for serialization
        /// </summary>
        public Setting()
        {
            this.Value = NotSet.Value;
            this.Text = NotSet.Text;
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="value"></param>
        private Setting(SettingValues value)
        {
            string key = "Setting" + value;
            this.Value = value;
            this.Text = Properties.Resources.ResourceManager.GetString(key);
            if (String.IsNullOrEmpty(this.Text)) throw new ArgumentOutOfRangeException("No text for " + key);
        }

        /// <summary>
        /// ValueFt
        /// </summary>
        public SettingValues Value { get; set; }

        /// <summary>
        /// Text
        /// </summary>
        [XmlIgnore]
        public string Text { get; private set; }

        /// <summary>
        /// Required, to check by value as value as result of serialization
        /// </summary>
        /// <param name="otherSetting"></param>
        /// <returns></returns>
        public override bool Equals(object otherSetting)
        {
            if (otherSetting == this) return true;
            Setting os = otherSetting as Setting;
            if (os == null) return false;
            return os.Value == this.Value;
        }

        /// <summary>
        /// Hashcode
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.Value.GetHashCode();
        }

        /// <summary>
        /// Meaningful representation
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            int v = (int) this.Value;
            return v.ToString(CultureInfo.InvariantCulture) + " " + this.Value.ToString() + ": " + this.Text;
        }

        /// <summary>
        /// ValueFt to single object.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Setting BySettingValue(SettingValues value)
        {
            return AllSettings.FirstOrDefault(setting => setting.Value == value);
        }
    }
}